/*
 License
 
 Copyright © 2012 Kevin Kimmich
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 in the Software without restriction, including without limitation the rights to 
 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 the Software, and to permit persons to whom the Software is furnished to do so, 
 subject to the following conditions:
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 @file
 This is the main include file for libcore.
 */

#ifndef _crcore_h
#define _crcore_h

#ifdef __cplusplus
extern "C" {
#endif	

#ifdef ENABLE_LIBXML
#include <libxml/parser.h>
#include <libxml/xpath.h>
#endif
#include <zlib.h>
#ifdef ENABLE_SSL
#include <openssl/ssl.h>
#endif
#include <dirent.h>
#include <netinet/in.h>

#include "crtypes.h"
#include "exception.h"
#include "list.h"
#include "core_thread.h"
#include "hash_string_to_pointer.h"
#include "stringbuffer.h"
#include "stream.h"
#include "hashtable.h"
#ifdef ENABLE_LIBXML
#include "xmlutils.h"
#endif


/*!
 Initializes the library. Call this before using any functions.
 */
void crcore_init(void);

/*!
 Maps a file into read-only memory. Returns NULL on failure, a pointer to the first byte of the file on success.
 @param filename The name of the file to map.
 @param no_swap Set to 1 to lock into memory
*/
void* map_file(mapped_file_t* mf, const char* filename, int no_swap);

/*!
 Unmaps the previously mapped file and cleans up any resources.
 @param f the previously mapped file.
 */
void unmap_file(mapped_file_t* f);

/*!
 Dump a memory region as a string to stdout.
 @param buf a pointer to the memory region.
 @param count the count of bytes to dump.
 */
void dump_buf(unsigned char* buf, int count);

/*!
 Initialize a timespec structure for a timeout call.
 @param now the current time
 @param timeout_msec the timeout in msec
 */
void set_timespec( struct timespec* now, int timeout_msec);

/*!
 Sets the start for measuring an elapsed time.
 @param e the elapso structure
 */
void __start_me(struct elapso* e);

/*!
 Stops the timer and returns the elapsed time in sec.
 @param e the elapso structure
 */ 
double __stop_me(struct elapso* e);

/*!
 Daemonizes a process.
 */
void daemon_init(void);

/*!
 Iterate on all the files in the path, calls "callback" for each file or directory.
 @param path The path to iterate on.
 @param count a pointer to a "count" integer for use by the callback.
 @param obj a private pointer to pass to the callback
 @param callback the callback function
 */
int iterate_files(const char* path, int* count, void* obj, iterate_file_callback callback);


/*!
 Allocate and return a UUID string. Caller should free.
 */
char* uuid_string(void);

/*!
 free memory if ptr != NULL
 */
void conditional_free( void* ptr );

/*!
 Splits a string into a number of substrings separated by delimeter.
 
 If buf is NULL, return 0 and items==NULL. If buf has no delimeter, return count is one, and
 a copy of buf is returned. If there is one or more delimeters, the number of substrings is returned
 and a copy of each substring is in the items array. Zero length strings are returned for back to back delims
 The caller must free the strings in the items array AND free the items array.
 @param buf The string to separate
 @param buflen The length of the string
 @param items Pointer to an array of char**
 @param delimeter The delimeter character, e.g. "/"
 */
int split(char* buf, int buflen, char*** items, char* delimeter);

/*!
 * decode base64 encoded data
 *
 * @param source the encoded data (zero terminated)
 * @param target pointer to the target buffer
 * @param targetlen length of the target buffer
 * @return length of converted data on success, -1 otherwise
 */ 
size_t base64_decode(char *source, unsigned char *target, size_t targetlen);

/**
 * encode an array of bytes using Base64 (RFC 3548)
 *
 * @param source the source buffer
 * @param sourcelen the length of the source buffer
 * @param target the target buffer
 * @param targetlen the length of the target buffer
 * @return 1 on success, 0 otherwise
 */  
int base64_encode(unsigned char *source, size_t sourcelen, char *target, size_t targetlen);

/**
 Does str1 end with str2? return pointer in str1, or NULL.
 @param str1 The string to search.
 @param str2 The string to search for.
 */
const char* strendswith( const char* str1, const char* str2 );
	

/**
	 * initialize a socket address structure from an address string and a port.
	 */
void address_init( struct sockaddr_in* addr, const char* address, uint16_t port );

	
#ifdef __cplusplus
}
#endif	
	
	
#endif
